#ifndef _ERP_GISMAPGATEWAYAO_GISMAP_HANDLER_H_
#define _ERP_GISMAPGATEWAYAO_GISMAP_HANDLER_H_

#include <map>
#include "erp/gis/po/coordinatespo_gis.h"
#include "http_comm/intf_http_client.h"
#include "http_comm/http_request.h"
#include "c2cplatform/library/basic/singleton_t.h"

using namespace erp::gis::po;
using namespace comm::http::custorm;


namespace erp
{
namespace gis
{
namespace ao
{
typedef struct SGisMapParam{
	uint32_t dwApiType;
	
	std::string strAddress;
	std::string strCity;
};

typedef struct SPoints{
	std::string strX;
	std::string strY;
};

class CGisMapRequest;
class CGisMapHandler
{
public:
	CGisMapHandler();
	~CGisMapHandler();
	
	template <typename T>
	bool RegisterMapRequest(uint32_t dwApiType)
	{
		CGisMapRequest* pGisMapRequest = new T();
		std::map<uint32_t, CGisMapRequest*>::const_iterator it = m_mapGisMapRequest.find(dwApiType);
		if (it == m_mapGisMapRequest.end())
		{
			m_mapGisMapRequest[dwApiType] = pGisMapRequest;
			return true;
		}
		delete pGisMapRequest;
		pGisMapRequest = NULL;
		return false;
	}

	void Destroy();
	
	int GetCoordinates( 
		const SGisMapParam& stGisMapParam, 
		std::vector<CCoordinatesPo>& vecCoordinates);
	
	const std::string& GetLastErrMsg() const;

private:
	std::string m_strErrMsg;
	std::map<uint32_t, CGisMapRequest*> m_mapGisMapRequest;
};

class CGisMapRequest
{
public:
	CGisMapRequest();
	virtual ~CGisMapRequest();

	virtual int DoRequest(
		const SGisMapParam& stGisMapParam, 
		std::vector<CCoordinatesPo>& vecCoordinates);
	
	const virtual std::string& GetLastErrMsg() const;

protected:
	virtual void InitRequestParam(const SGisMapParam& stGisMapParam);
	virtual void GenWebRequest(CHttpRequest& oWebRequest);
	virtual int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates)
	{ 
		return 0;
	}
	virtual void RefleshProxy()
	{
	}
	

protected:
	// global info.
	std::string m_strMapName;
	std::string m_strErrMsg;
	std::string m_strUrlTemplate;
	std::string m_strProxy;
	uint32_t m_dwProxyPort;
	uint32_t m_dwTimeout;
	uint32_t m_dwRequestErrNum;
	
	uint32_t m_dwParseErrItil;
	uint32_t m_dwCheckErrItil;
	uint32_t m_dwSuccessItil;
	uint32_t m_dwInvalidErrItil;
	uint32_t m_dwRequestErrItil;
	uint32_t m_dwReqLimitedErrItil;

	SGisMapParam m_stGisMapParam;	
	IHttpClient* m_pHttpClient;
};

class CSoSoRequest: public CGisMapRequest
{
public:
	CSoSoRequest();
	virtual ~CSoSoRequest(){}

private:
	struct SJsonSoso {
		// info
		int iError;
		
		// posis
		std::vector<SPoints> vecPoints;
	};
	
	int  ParseJsonData(const std::string& strJson, SJsonSoso& stJsonSoso);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	void RefleshProxy();
	
};


class CSoSo2Request: public CGisMapRequest
{
public:
	CSoSo2Request();
	virtual ~CSoSo2Request() {}

private:
	struct SJsonSoso2 {
		// info
		int iError;
		
		// detail
		int iGpsType;
		SPoints stPoints;
		double dbSimilarity;
	};
	
	int  ParseJsonData(const std::string& strJson, SJsonSoso2& stJsonSoso2);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	bool CheckJsonData(const SJsonSoso2& stJsonSoso2);
	void RefleshProxy();
};


class CBaiduRequest: public CGisMapRequest
{
public:
	CBaiduRequest();
	virtual ~CBaiduRequest() {}

private:
	struct SJsonBaidu {
		std::string strStatus;
		std::string strLevel;
		
		SPoints stLocation;
		
		int iPrecise;
		double dbConfidence;
		
	};
	
	int  ParseJsonData(const std::string& strJson, SJsonBaidu& stJsonBaidu);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	bool CheckJsonData(const SJsonBaidu& stJsonBaidu);
	void RefleshProxy();
};



class CGoogleRequest: public CGisMapRequest
{
public:
	CGoogleRequest();
	virtual ~CGoogleRequest() {}

private:
	struct SGoogleLocation {
		SPoints stLocation;
		std::vector<std::string> vecTypes;
	};

	struct SJsonGoogle{
		std::string strStatus;
		std::vector<SGoogleLocation> vecLocations;
	};
	
	int  ParseJsonData(const std::string& strJson, SJsonGoogle& stJsonGoogle);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	void FilterLocation(SJsonGoogle& stJsonGoogle);
	void RefleshProxy();
};


class CAliyunRequest: public CGisMapRequest
{
public:
	CAliyunRequest();
	virtual ~CAliyunRequest() {}

private:
	struct SJsonAliyun {
		int iLevel;
		int iAlevel;
		SPoints stPoints;
	};
	
	int  ParseJsonData(const std::string& strJson, SJsonAliyun& stJsonAliyun);
	bool CheckJsonData(const SJsonAliyun& stJsonAliyun);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	void RefleshProxy();
};

class CGaodeRequest: public CGisMapRequest
{
public:
	CGaodeRequest();
	virtual ~CGaodeRequest() {}

private:
	struct SJsonGaode{
		std::string strLevel;
		double dbScore;
		
		SPoints stPoints;
	};
	
	int  ParseJsonData(const std::string& strJson, std::vector<SJsonGaode>& stJsonGaode);
	int  ParseCoordinate(const std::string& strResponseBody, std::vector<CCoordinatesPo>& vecCoordinates);
	void FilterJsonData(std::vector<SJsonGaode>& stJsonGaode);
	void RefleshProxy();
};


typedef CSingletonT<CGisMapHandler, CDummyLock> CGisMapHandlerSingleton;
#define CGIS_MAP_HANDLER			CGisMapHandlerSingleton::Instance()

}
}
}

#endif /*_ERP_GISMAPGATEWAYAO_GISMAP_HANDLER_H_*/

